/*
 * RTSAI - Real-Time Strategy engine for AI research
 * Copyright(C) 2006 DIMAp-UFRN, licensed under LGPL
 *
 * Game event
 */

#include <iostream>
#include <string>
#include "Game.h"
#include "GameEvent.h"
#include "UnitState.h"
#include "Common.h"

/*! Creates a new game event and registers it in the game.
 *  @param event_name Name of the created event
 */
GameEvent::GameEvent ( const std::string &event_name = "default" )
{
    name = event_name;
    Game::getInstance().register_event ( this );
}


/*! When an event is deleted, it is removed from the registered events in
 *  the game.
 */
GameEvent::~GameEvent()
{
    Game::getInstance().unregister_event ( this );
}


/*! Notify all the listeners with the data generated by the event.
 *  @param data TODO
 */
void GameEvent::notify_listeners ( GameEventData* data )
{
    // we are not using the foreach macro here because change_state() delete the
    // current state pointed by the iterator. It's then necessary to jump one
    // position ( ++it ) before calling change_state()
    StateList::iterator it = listeners.begin();

    while ( it != listeners.end() )
    {
        UnitState *current_state = (*it);

        ++it;

        UnitState *new_state = current_state -> react_to_event (
                                                this->get_name(), data );
        if ( new_state )
        {
            Unit *unit = current_state -> unit;
            unit -> change_state ( new_state );
        }
    }
}


/*! Add a listener (state), which means that the state will be notified as soon
 *  as the event happens.
 *  @param state A state that will be added to listen this event
 */
void GameEvent::add_listener ( UnitState *state )
{
    listeners.push_front ( state );
}


/*! Remove a listener (state), which means that when the event happens the
 *  state will not be notified.
 *  @param state A state that will be removed from the listeners of this event
 */
void GameEvent::remove_listener ( UnitState *state )
{
    listeners.remove ( state );
}
